package com.aegean.CommercialHotelBookSystem.hotel.dao.Impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.aegean.CommercialHotelBookSystem.factory.HibernateSessionFactory;
import com.aegean.CommercialHotelBookSystem.hotel.dao.IHotelDao;
import com.aegean.CommercialHotelBookSystem.model.Hotel;

public class HotelDaoImpl implements IHotelDao {
	public Hotel searchHotel(String hotelName) {
		Session session = null;
		Transaction tx = null;
		Hotel one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Query q = session.createQuery("from Hotel where hotel_Name=:name");
			q.setString("name", hotelName);
			q.setCacheable(true);
			one = (Hotel) q.uniqueResult();
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public Session getSession() {
		return HibernateSessionFactory.getSession();
	}

	@Override
	public void closeSession() {
		HibernateSessionFactory.closeSession();
	}

	@Override
	public Hotel saveHotel(Hotel obj) {
		Session session = null;
		Transaction tx = null;
		Hotel one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			session = getSession();
			tx = session.beginTransaction();
			if (obj instanceof Hotel) {
				one = (Hotel) obj;
				session.save(one);
				tx.commit();
			}
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}

	}

	@Override
	public List<Hotel> searchHotelList(int intpage, int intpagesize,
			String name, String city) {
		int numBegin = 0;
		if (intpage < 1) {
			numBegin = 0;
		} else {
			numBegin = (intpage - 1) * intpagesize;
		}
		DetachedCriteria dcr = DetachedCriteria.forClass(Hotel.class);
		if (name != null && !name.equals("")) {
			dcr.add(Restrictions.like("hotel_Name", "%" + name + "%"));
		} else if (city != null && !city.equals("")) {
			dcr.add(Restrictions.like("hotel_Address.city", "%" + city + "%"));
		}
		Session session = null;
		Transaction tx = null;
		List<Hotel> hotels = new ArrayList<Hotel>();
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = dcr.getExecutableCriteria(session);
			cr.setFirstResult(numBegin);
			cr.setMaxResults(intpagesize);
			cr.setCacheable(true);
			hotels = cr.list();
			tx.commit();
			return hotels;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public int searchHotelListCount(String name, String city) {
		DetachedCriteria dcr = DetachedCriteria.forClass(Hotel.class);
		if (name != null && !name.equals("")) {
			dcr.add(Restrictions.like("hotel_Name", "%" + name + "%"));
		} else if (city != null && !city.equals("")) {
			dcr.add(Restrictions.like("hotel_Address.city", "%" + city + "%"));
		}
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = dcr.getExecutableCriteria(session);
			cr.setProjection(Projections.projectionList());
			cr.setCacheable(true);
			int count = (Integer) cr.setProjection(Projections.rowCount())
					.uniqueResult();
			return count;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			closeSession();
		}
	}

	@Override
	public Hotel editHotel(Hotel obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			if (obj instanceof Hotel) {
				session.merge(obj);
				tx.commit();
			}
			return obj;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}
}
